package com.hsy.crm.web.service.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.hsy.crm.web.domain.cm.App;
import com.hsy.crm.web.domain.cm.PageResult;
import com.hsy.crm.web.domain.cm.Unified;
import com.hsy.crm.web.domain.entity.FinTransOrder;
import com.hsy.crm.web.domain.entity.FinTransOrderDetail;
import com.hsy.crm.web.domain.po.fintrans.FinTransOrderPagePo;
import com.hsy.crm.web.domain.po.fintrans.FinTransOrderPo;
import com.hsy.crm.web.domain.vo.fintrans.FinTransInsertVo;
import com.hsy.crm.web.domain.vo.fintrans.FinTransPageVo;
import com.hsy.crm.web.mapper.FinTransOrderDetailMapper;
import com.hsy.crm.web.mapper.FinTransOrderMapper;
import com.hsy.crm.web.service.base.BaseService;
import com.hsy.crm.web.service.base.DataInitService;
import com.hsy.crm.web.utils.UuidUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

@Service
public class FinTranService  extends BaseService<FinTransOrder> {

    @Autowired
    FinTransOrderDetailMapper finTransOrderDetailMapper;

    @Autowired
    FinTransOrderMapper finTransOrderMapper;

    @Autowired
    AccountService accountService;

    @Transactional
    public Unified<Integer> examine(FinTransOrder order) {
        FinTransOrder dbOrder = finTransOrderMapper.selectByPrimaryKey(order);
        dbOrder.setCustomerId(order.getCustomerId());
        Unified<Integer> unified = this.updateStatus(dbOrder,App.Status.SH);
        return unified;
    }

    @Transactional
    public Unified<Integer> doInvalid(FinTransOrder order) {
        FinTransOrder dbOrder = finTransOrderMapper.selectByPrimaryKey(order);
        dbOrder.setCustomerId(order.getCustomerId());
        Unified<Integer> unified = this.updateStatus(dbOrder,App.Status.BC);
        return unified;
    }

    @Transactional
    public Unified<FinTransOrder> insertFinTransOrder(FinTransInsertVo vo) {
        Unified<FinTransOrder> unified = new Unified<>();

        FinTransOrder order = vo.getOrder();
        order.setCustomerId(vo.getCustomerId());
        order.setLoginUserId(vo.getLoginUserId());
        order.setLoginCompanyId(vo.getLoginCompanyId());
        order.setCode(DataInitService.getOrderCode());
        order.setStatus(App.Status.BC);

        this.insert(order);

        this.insertDetails(vo);

        if( vo.getSaveType() == App.SaveType.EXAMINE ){
            examine(order);
        }

        unified.setData(order);

        return unified;
    }

    @Transactional
    public Unified<FinTransOrder> updateFinTransOrder(FinTransInsertVo vo) {
        Unified<FinTransOrder> unified = new Unified<>();

        FinTransOrder order = vo.getOrder();
        order.setCustomerId(vo.getCustomerId());
        finTransOrderMapper.updateByPrimaryKeySelective(order);

        this.deleteDetails(vo.getOrder());
        this.insertDetails(vo);

        if( vo.getSaveType() == App.SaveType.EXAMINE ){
            examine(order);
        }

        unified.setData(order);
        return unified;
    }

    @Transactional
    public Unified<Integer> deleteFinTransOrder(FinTransOrder order) {
        this.deleteDetails(order);
        return Unified.newInstance(this.delete(order));
    }

    public PageResult<FinTransOrderPagePo> page(FinTransPageVo finTransPageVo) {
        Page page = PageHelper.startPage(finTransPageVo.getPage(),finTransPageVo.getLimit());
        PageResult<FinTransOrderPagePo> pageResult = new PageResult<>();
        pageResult.setRows(finTransOrderMapper.page(finTransPageVo));
        pageResult.setTotal(page.getTotal());
        return pageResult;
    }

    public Unified<FinTransOrderPo> getOrder(FinTransOrder order) {
        Unified<FinTransOrderPo> unified = new Unified<>();
        FinTransOrderPo po = new FinTransOrderPo();
        po.setOrder(finTransOrderMapper.getOrder(order));
        po.setDetails(finTransOrderMapper.getOrderDetails(order));
        unified.setData(po);
        return unified;
    }

    private void deleteDetails(FinTransOrder order){
        FinTransOrderDetail detail = new FinTransOrderDetail();
        detail.setCustomerId(order.getCustomerId());
        detail.setFinTransOrderId(order.getId());
        finTransOrderDetailMapper.delete(detail);
    }

    private void insertDetails(FinTransInsertVo vo){
        Long finTransOrderId = vo.getOrder().getId();
        for(FinTransOrderDetail detail : vo.getDetails() ){
            detail.setCustomerId(vo.getCustomerId());
            detail.setFinTransOrderId(finTransOrderId);
            detail.setId(UuidUtils.getUuid());
            finTransOrderDetailMapper.insert(detail);
        }
    }

    private Unified<Integer> updateStatus(FinTransOrder order,int status){
        Unified<Integer> unified = new Unified<>();
        String customerId = order.getCustomerId();

        FinTransOrder updateOrder = new FinTransOrder();
        updateOrder.setId(order.getId());
        updateOrder.setCustomerId(customerId);
        updateOrder.setStatus(status);
        finTransOrderMapper.updateByPrimaryKeySelective(updateOrder);

        FinTransOrderDetail detail = new FinTransOrderDetail();
        detail.setFinTransOrderId(order.getId());
        detail.setCustomerId(order.getCustomerId());
        List<FinTransOrderDetail> details = finTransOrderDetailMapper.select(detail);

        if( status == App.Status.SH ){
            for( FinTransOrderDetail transDetail : details ){
                // out
                accountService.updateBalance(customerId,transDetail.getOutAccountId(),transDetail.getPrice(),App.Direction.SUB);
                // in
                accountService.updateBalance(customerId,transDetail.getInAccountId(),transDetail.getPrice(),App.Direction.ADD);
            }
        }else{
            for( FinTransOrderDetail transDetail : details ){
                // out
                accountService.updateBalance(customerId,transDetail.getOutAccountId(),transDetail.getPrice(),App.Direction.ADD);
                // in
                accountService.updateBalance(customerId,transDetail.getInAccountId(),transDetail.getPrice(),App.Direction.SUB);
            }
        }


        return unified;
    }


}
